package leetcode.editor.cn.q301_600.q300;
//给定一个二维矩阵 matrix，以下类型的多个请求： 
//
// 
// 计算其子矩形范围内元素的总和，该子矩阵的 左上角 为 (row1, col1) ，右下角 为 (row2, col2) 。 
// 
//
// 实现 NumMatrix 类： 
//
// 
// NumMatrix(int[][] matrix) 给定整数矩阵 matrix 进行初始化 
// int sumRegion(int row1, int col1, int row2, int col2) 返回 左上角 (row1, col1) 、右下
//角 (row2, col2) 所描述的子矩阵的元素 总和 。 
// 
//
// 
//
// 示例 1： 
//
// 
//
// 
//输入: 
//["NumMatrix","sumRegion","sumRegion","sumRegion"]
//[[[[3,0,1,4,2],[5,6,3,2,1],[1,2,0,1,5],[4,1,0,1,7],[1,0,3,0,5]]],[2,1,4,3],[1,
//1,2,2],[1,2,2,4]]
//输出: 
//[null, 8, 11, 12]
//
//解释:
//NumMatrix numMatrix = new NumMatrix([[3,0,1,4,2],[5,6,3,2,1],[1,2,0,1,5],[4,1,
//0,1,7],[1,0,3,0,5]]);
//numMatrix.sumRegion(2, 1, 4, 3); // return 8 (红色矩形框的元素总和)
//numMatrix.sumRegion(1, 1, 2, 2); // return 11 (绿色矩形框的元素总和)
//numMatrix.sumRegion(1, 2, 2, 4); // return 12 (蓝色矩形框的元素总和)
// 
//
// 
//
// 提示： 
//
// 
// m == matrix.length 
// n == matrix[i].length 
// 1 <= m, n <= 200
// 
// -10⁵ <= matrix[i][j] <= 10⁵ 
// 0 <= row1 <= row2 < m 
// 0 <= col1 <= col2 < n 
// 
// 最多调用 10⁴ 次 sumRegion 方法 
// 
//
// 👍 507 👎 0

import leetcode.editor.cn.util.arr.ArrayUtil;

/**
 * 没啥好思路，保存一个新的矩阵 sum，sum 中每个元素都代表了 matrix 在 【0 0】 到 【row col】坐标的和
 * <p>
 * 通过这个和就可以比较快计算出结果
 * <p>
 * 执行耗时:99 ms,击败了88.29% 的Java用户
 * 内存消耗:64.2 MB,击败了76.31% 的Java用户
 */
public class Q304_RangeSumQuery2dImmutable {
    //leetcode submit region begin(Prohibit modification and deletion)
    class NumMatrix {

        // 每个坐标都是以改坐标为右下角的长方形的和
        private int[][] sum;

        public NumMatrix(int[][] matrix) {
            int m = matrix.length;
            int n = matrix[0].length;
            sum = new int[m][n];
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    if (i == 0) {
                        if (j == 0) {
                            sum[0][0] = matrix[0][0];
                        } else {
                            sum[0][j] = sum[0][j - 1] + matrix[0][j];
                        }
                    } else if (j == 0) {
                        sum[i][0] = sum[i - 1][0] + matrix[i][0];
                    } else {
                        sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + matrix[i][j];
                    }
                }
            }
        }

        public int sumRegion(int row1, int col1, int row2, int col2) {
            if (row1 == 0) {
                if (col1 == 0) {
                    return sum[row2][col2];
                }
                return sum[row2][col2] - sum[row2][col1 - 1];
            } else if (col1 == 0) {
                return sum[row2][col2] - sum[row1 - 1][col2];
            } else {
                return sum[row2][col2] - sum[row1 - 1][col2] - sum[row2][col1 - 1] + sum[row1 - 1][col1 - 1];
            }
        }
    }

    /**
     * Your NumMatrix object will be instantiated and called as such:
     * NumMatrix obj = new NumMatrix(matrix);
     * int param_1 = obj.sumRegion(row1,col1,row2,col2);
     */
    //leetcode submit region end(Prohibit modification and deletion)
    public static void main(String[] args) {
        NumMatrix numMatrix = new Q304_RangeSumQuery2dImmutable().new NumMatrix((int[][]) ArrayUtil.genArrayByString(
                "[" +
                        "[3,0,1,4,2]," +
                        "[5,6,3,2,1]," +
                        "[1,2,0,1,5]," +
                        "[4,1,0,1,7]," +
                        "[1,0,3,0,5]]"));
        System.out.println(numMatrix.sumRegion(2, 1, 4, 3)); // return 8 (红色矩形框的元素总和)
        System.out.println(numMatrix.sumRegion(1, 1, 2, 2)); // return 11 (绿色矩形框的元素总和)
        System.out.println(numMatrix.sumRegion(1, 2, 2, 4)); // return 12 (蓝色矩形框的元素总和)
    }
}